package com.ruoyi.system.service.impl;

import com.ruoyi.common.core.domain.ApiResponse;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.vo.Packages;
import com.ruoyi.system.domain.vo.TaskMessage;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.service.IPendingTaskService;
import com.ruoyi.system.service.ITbDownloadTokenService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class PendingTaskServiceIpml implements IPendingTaskService {

    @Resource
    private TbDeviceInfoMapper deviceInfoMapper;


    @Resource
    private TbDeviceMapper tbDeviceMapper;


    @Resource
    private TbTaskDetailMapper tbTaskDetailMapper;

    @Resource
    private TbTaskMapper tbTaskMapper;


    @Resource
    private TbTaskTargetMapper taskTargetMapper;


    @Resource
    private TbAppVersionMapper tbAppVersionMapper;


    @Resource
    private TbDataPackageMapper dataPackageMapper;


    @Autowired
    private ITbDownloadTokenService downloadTokenService;  // 【新增】下载令牌服务


    @Autowired
    private TbOfflineTaskDetailLogsMapper offlineTaskDetailLogsMapper;


    @Override
    public TaskMessage getDeviceAllPendingTasksOrder(String devSN) {
        log.info("查询任务接口-设备号: {}", devSN);

        if (StringUtils.isBlank(devSN)) {
            log.warn("设备号为空");
            return createEmptyTaskMessage();
        }

        try {
            TbDevice device = tbDeviceMapper.selectByDeviceSn(devSN);
            if (device == null) {
                log.warn("设备不存在: {}", devSN);
                return createEmptyTaskMessage();
            }

            TaskMessage nextTask = getNextPendingTaskForDevice(device.getId());
            if (nextTask == null) {
                log.info("设备 {} 没有待执行任务", devSN);
                return createEmptyTaskMessage();
            }

            log.info("获取设备下一个待执行任务成功，任务ID: {}", nextTask.getTaskId());
            return nextTask;

        } catch (Exception e) {
            log.error("获取设备待执行任务失败, 设备号: {}", devSN, e);
            return createEmptyTaskMessage();
        }
    }

    // 创建空任务消息的辅助方法
    private TaskMessage createEmptyTaskMessage() {
        TaskMessage taskMessage = new TaskMessage();
        taskMessage.setPackages(new ArrayList<>());
        return taskMessage;
    }

    /**
     * 获取设备下一个待执行的任务（只返回一个）
     */
    private TaskMessage getNextPendingTaskForDevice(Long deviceId) {
        // 1. 获取设备所有待执行的任务目标
        List<TbTaskTarget> pendingTaskTargets = taskTargetMapper.selectPendingTargetByDeviceId(deviceId);
        if (CollectionUtils.isEmpty(pendingTaskTargets)) {
            return createEmptyTaskMessage();
        }

        // 2. 按任务ID分组并排序
        Map<Long, List<TbTaskTarget>> taskTargetsByTaskId = groupAndSortTaskTargets(pendingTaskTargets);
        if (taskTargetsByTaskId.isEmpty()) {
            return createEmptyTaskMessage();
        }

        // 3. 找到第一个未完成的任务
        Long nextTaskId = findNextTaskId(taskTargetsByTaskId, deviceId);
        if (nextTaskId == null) {
            return createEmptyTaskMessage();
        }

        // 4. 获取该任务的信息
        List<TbTaskTarget> nextTaskTargets = taskTargetsByTaskId.get(nextTaskId);
        TbTask task = tbTaskMapper.selectTbTaskById(nextTaskId);
        if (task == null) {
            log.warn("任务不存在，任务ID: {}", nextTaskId);
            return createEmptyTaskMessage();
        }

        // 5. 转换任务消息
        return convertToTaskMessage(task, nextTaskTargets, deviceId);
    }

    /**
     * 按任务ID分组并按任务优先级和创建时间排序
     */
    private Map<Long, List<TbTaskTarget>> groupAndSortTaskTargets(List<TbTaskTarget> taskTargets) {
        Map<Long, List<TbTaskTarget>> result = new LinkedHashMap<>();

        for (TbTaskTarget target : taskTargets) {
            TbTaskDetail detail = tbTaskDetailMapper.selectTbTaskDetailById(target.getTaskDetailId());
            if (detail != null) {
                result.computeIfAbsent(detail.getTaskId(), k -> new ArrayList<>()).add(target);
            }
        }

        return result;
    }

    /**
     * 找到下一个应该执行的任务ID
     */
    private Long findNextTaskId(Map<Long, List<TbTaskTarget>> taskTargetsByTaskId, Long deviceId) {
        List<Long> sortedTaskIds = getSortedTaskIds(taskTargetsByTaskId.keySet());

        for (Long taskId : sortedTaskIds) {
            if (!isTaskCompletedForDevice(taskId, deviceId)) {
                return taskId;
            }
        }
        return null;
    }

    /**
     * 按任务优先级和创建时间排序任务ID
     */
    private List<Long> getSortedTaskIds(Set<Long> taskIds) {
        if (CollectionUtils.isEmpty(taskIds)) {
            return new ArrayList<>();
        }

        List<TbTask> tasks = tbTaskMapper.selectTasksByIds(new ArrayList<>(taskIds));

        return tasks.stream()
                .sorted(Comparator.comparingInt(TbTask::getTaskPriority)
                        .thenComparing(TbTask::getRegistrationTime))
                .map(TbTask::getId)
                .collect(Collectors.toList());
    }

    /**
     * 检查某个任务是否已经全部完成（针对特定设备）
     */
    private boolean isTaskCompletedForDevice(Long taskId, Long deviceId) {
        List<TbTaskDetail> taskDetails = tbTaskDetailMapper.selectByTaskId(taskId);

        for (TbTaskDetail detail : taskDetails) {
            TbTaskTarget target = taskTargetMapper.selectByDetailIdAndDeviceId(detail.getId(), deviceId);
            if (target != null && (target.getStatus() == 0 || target.getStatus() == 1)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 转换任务消息
     */
    private TaskMessage convertToTaskMessage(TbTask task, List<TbTaskTarget> taskTargets, Long deviceId) {
        TaskMessage taskMessage = new TaskMessage();
        taskMessage.setTaskId(task.getId());
        taskMessage.setTaskname(task.getTaskName());

        List<Packages> packages = taskTargets.stream()
                .filter(target -> target.getStatus() == 0) // 只处理待执行状态
                .map(target -> getPackagesForTaskTarget(target, deviceId))
                .filter(Objects::nonNull)
                .flatMap(List::stream)
                .collect(Collectors.toList());

        taskMessage.setPackages(packages);
        return taskMessage;
    }

    private List<Packages> getPackagesForTaskTarget(TbTaskTarget taskTarget, Long deviceId) {
        TbTaskDetail taskDetail = tbTaskDetailMapper.selectTbTaskDetailById(taskTarget.getTaskDetailId());
        if (taskDetail == null) {
            return Collections.emptyList();
        }

        switch (taskDetail.getTaskType()) {
            case 3: // 应用安装
            case 4: // 应用升级
                Packages appPackage = getAppPackage(taskDetail, deviceId);
                return appPackage != null ? Collections.singletonList(appPackage) : Collections.emptyList();
            case 5: // 应用卸载
                Packages uninstallPackage = getUninstallPackage(taskDetail);
                return uninstallPackage != null ? Collections.singletonList(uninstallPackage) : Collections.emptyList();
            case 1: // 数据推送
            case 2: // 数据更新
                Packages dataPackage = getDataPackage(taskDetail);
                return dataPackage != null ? Collections.singletonList(dataPackage) : Collections.emptyList();
            default:
                return Collections.emptyList();
        }
    }

    private Packages getAppPackage(TbTaskDetail taskDetail, Long deviceId) {
        TbAppVersion newVersion = tbAppVersionMapper.selectByPackageIdAndCode(
                taskDetail.getPackageId(),
                taskDetail.getPackageVersioncode(),
                taskDetail.getPackageVersionnumber());

        if (newVersion == null) {
            return null;
        }

        Packages pkg = new Packages();
        String packageName = tbAppVersionMapper.selectByPackageNameByCondition(
                taskDetail.getPackageVersionnumber(),
                taskDetail.getPackageVersioncode(),
                taskDetail.getAppName());

        pkg.setAppname(packageName);
        pkg.setAppversion(newVersion.getPackageVersionnumber());
        pkg.setVersioncode(Integer.valueOf(newVersion.getPackageVersioncode()));

        // 获取设备上最近一次已安装的旧版本(离线和在线)
        TbAppVersion oldVersion = getInstalledOldVersion(deviceId, taskDetail);

        if (oldVersion != null) {
            TbAppVersion diffPackage = findDiffPackage(oldVersion, newVersion);

            if (diffPackage != null) {
                // 差分包
                setDiffPackageInfo(pkg, oldVersion, newVersion, diffPackage);
                pkg.setPackageType(2);
            } else {
                // 全量包
                setFullPackageInfo(pkg, newVersion);
                pkg.setPackageType(1);
            }
        } else {
            // 全量包
            setFullPackageInfo(pkg, newVersion);
            pkg.setPackageType(1);
        }

        return pkg;
    }

    /**
     * 获取设备上已安装的旧版本
     */
    private TbAppVersion getInstalledOldVersion(Long deviceId, TbTaskDetail taskDetail) {
        TbAppVersion oldVersion = null;

        // 查询离线任务日志获取旧版本
        TbOfflineTaskDetailLogs offlineTaskLog = offlineTaskDetailLogsMapper.selectByConditions(
                deviceId, taskDetail.getAppName(),
                taskDetail.getPackageVersionnumber(),
                taskDetail.getPackageVersioncode());

        TbAppVersion offlineOldVersion = null;
        if (offlineTaskLog != null) {
            offlineOldVersion = tbAppVersionMapper.selectByPackageNameAndCodeAndNum(
                    offlineTaskLog.getPackageName(),
                    offlineTaskLog.getPackageVersioncode(),
                    offlineTaskLog.getPackageVersionnumber());
        }

        // 查询在线成功安装的版本
        TbAppVersion onlineOldVersion = getLastSuccessAppVersion(
                deviceId, taskDetail.getAppName(), taskDetail.getPackageVersioncode());

        // 比较两个版本，选择版本号较大的
        if (offlineOldVersion != null && onlineOldVersion != null) {
            // 两个版本都存在，选择版本号较大的
            if (compareVersions(offlineOldVersion, onlineOldVersion) > 0) {
                oldVersion = offlineOldVersion;
            } else {
                oldVersion = onlineOldVersion;
            }
        } else if (offlineOldVersion != null) {
            // 只有离线版本
            oldVersion = offlineOldVersion;
        } else if (onlineOldVersion != null) {
            // 只有在线版本
            oldVersion = onlineOldVersion;
        }

        return oldVersion;
    }

    /**
     * 比较两个版本号
     * 返回正数表示version1 > version2，负数表示version1 < version2，0表示相等
     */
    private int compareVersions(TbAppVersion version1, TbAppVersion version2) {
        if (version1 == null || version2 == null) {
            return 0;
        }

        try {
            int code1 = Integer.parseInt(version1.getPackageVersioncode());
            int code2 = Integer.parseInt(version2.getPackageVersioncode());
            return Integer.compare(code1, code2);
        } catch (NumberFormatException e) {
            log.warn("版本号比较失败: {} vs {}",
                    version1.getPackageVersioncode(), version2.getPackageVersioncode());
            return 0;
        }
    }


    private TbAppVersion findDiffPackage(TbAppVersion oldVersion, TbAppVersion newVersion) {
        return tbAppVersionMapper.selectDiffPackageByVersions(oldVersion.getPackageName(),
                oldVersion.getPackageVersioncode(), oldVersion.getPackageVersionnumber(), newVersion.getPackageVersioncode()
                , newVersion.getPackageVersionnumber());
    }

    private void setFullPackageInfo(Packages pkg, TbAppVersion version) {
        String fileName = extractFileNameFromUrl(version.getPackageUrl());
        pkg.setDownloadtoken(downloadTokenService.generateDownloadToken(version.getPackageUrl(), "OTA"));
        pkg.setHash(version.getPackageHash());
        pkg.setNewFileName(fileName);

        // 全量包不需要设置新旧版本信息，但为了完整性可以设置为null
        pkg.setOldfileName(null);
        pkg.setOldHash(null);
        pkg.setNewHash(null);
        pkg.setNewAppver(null);
        pkg.setOldAppver(null);
    }

    private void setDiffPackageInfo(Packages pkg, TbAppVersion oldVersion, TbAppVersion newVersion, TbAppVersion diffPackage) {
        String fileName = extractFileNameFromUrl(diffPackage.getPackageUrl());
        String token = downloadTokenService.generateDownloadToken(diffPackage.getPackageUrl(), "OTA");

        pkg.setDownloadtoken(token);
        pkg.setHash(diffPackage.getPackageHash());
        pkg.setNewFileName(fileName);

        // 设置新旧版本信息（包括新增的两个字段）
        pkg.setOldfileName(extractFileNameFromUrl(oldVersion.getPackageUrl()));
        pkg.setOldHash(oldVersion.getPackageHash());
        pkg.setNewHash(newVersion.getPackageHash());

        // 新增的两个字段
        pkg.setNewAppver(newVersion.getPackageVersionnumber()); // 新版本号
        pkg.setOldAppver(oldVersion.getPackageVersionnumber()); // 旧版本号
    }

    private String extractFileNameFromUrl(String url) {
        if (StringUtils.isBlank(url)) {
            return "unknown_file";
        }
        try {
            // 处理两种路径分隔符
            int lastSlashIndex = Math.max(url.lastIndexOf("/"), url.lastIndexOf("\\"));
            if (lastSlashIndex >= 0 && lastSlashIndex < url.length() - 1) {
                return url.substring(lastSlashIndex + 1);
            }
            return url;
        } catch (Exception e) {
            log.warn("从URL提取文件名失败: {}", url, e);
            return "download_file";
        }
    }

    private Packages getUninstallPackage(TbTaskDetail taskDetail) {
        Packages pkg = new Packages();
        pkg.setAppname(tbAppVersionMapper.selectByPackageNameByCondition(
                taskDetail.getPackageVersionnumber(),
                taskDetail.getPackageVersioncode(),
                taskDetail.getAppName()));
        pkg.setPackageType(4);
        return pkg;
    }

    private Packages getDataPackage(TbTaskDetail taskDetail) {
        TbDataPackage dataPackage = dataPackageMapper.selectTbDataPackageById(taskDetail.getPackageId());
        if (dataPackage == null) {
            return null;
        }

        Packages pkg = new Packages();
        //  String fileName = extractFileNameFromUrl(dataPackage.getPackageUrl());

        pkg.setDownloadtoken(downloadTokenService.generateDownloadToken(dataPackage.getPackageUrl(), "OTA"));
        pkg.setHash(dataPackage.getPackageHash());
        pkg.setAppname(dataPackage.getPackageName());
        pkg.setAppversion(dataPackage.getPackageVersionnumber());
        pkg.setVersioncode(Integer.valueOf(dataPackage.getPackageVersioncode()));
        pkg.setPackageType(3);

        return pkg;
    }

    private TbAppVersion getLastSuccessAppVersion(Long deviceId, String appName, String packageVersioncode) {
        List<TbTaskTarget> lastSuccessTargets = taskTargetMapper.selectLastSuccessTaskTargetByApp(deviceId, appName);

        if (CollectionUtils.isEmpty(lastSuccessTargets)) {
            return null;
        }

        TbTaskTarget lastTarget = lastSuccessTargets.get(0);
        TbTaskDetail taskDetail = tbTaskDetailMapper.selectTbTaskDetailById(lastTarget.getTaskDetailId());

        if (taskDetail != null && taskDetail.getPackageId() != null) {
            return tbAppVersionMapper.selectBYConditions(
                    taskDetail.getPackageId(),
                    taskDetail.getPackageVersionnumber(),
                    taskDetail.getPackageVersioncode());
        }
        return null;
    }
}
